package com.ruoyi.web.East;

import com.ruoyi.common.utils.BinaryUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.gas.domain.GasDf;
import com.ruoyi.gas.domain.GasWarnRectify;
import com.ruoyi.gas.service.IGasDfService;
import com.ruoyi.gas.service.IGasWarnRectifyService;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.net.Socket;

@Slf4j
public class SocketServer implements Runnable {

    private final Socket socket;
    public SocketServer(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try (InputStream is = socket.getInputStream();
             OutputStream os = socket.getOutputStream();
             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os))) {

            processConnection(is, writer);

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            closeSocket();
        }
    }

    /**
     * 接收客户端发送的数据
     *
     * @param is     输入流
     * @param writer 输出流
     * @throws IOException 异常
     */
    private void processConnection(InputStream is, BufferedWriter writer) throws IOException {
        byte[] buff = new byte[1024];
        int readlen;
        while ((readlen = is.read(buff)) != -1) {
            // 只保留客户端传过来的数据长度；调整暴力去除字节为0的数据，修改为通过传过来的数据长度进行处理，
            // 创建一个新的字节数组，长度为实际读取的字节数
            byte[] newBuff = new byte[readlen];
            // 将数据从buff复制到新数组data
            System.arraycopy(buff, 0, newBuff, 0, readlen);
            //判断是否接收完数据
            if (is.available()==0){
                processFrame(newBuff, writer);
            }
            // 处理数据
        }
    }

    /**
     * 处理请求帧
     *
     * @param newBuff 请求帧字节数据
     * @param writer  输出流 - 下发消息的时候用
     * @throws IOException 异常
     */
    private void processFrame(byte[] newBuff, BufferedWriter writer) throws IOException {
        // 转为16进制
        String hexString = ByteUtils.ByteArrayToHexStr(newBuff);
//        String hexString = "55 28 07 0D 2D 91 06 1D 00 00 00 25 00 00 00 2C 00 D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 01 00 00 8E B2 ";
        log.info("请求数据为：" + hexString);
        log.info("请求数据长度：" + hexString.length());
        // region TODO 解析数据

        if (hexString.length() == 120){
            //隐患汇总
            IGasWarnRectifyService rectifyService = SpringUtils.getBean(IGasWarnRectifyService.class);
            GasWarnRectify rectify=new GasWarnRectify();
            rectify.setWarnTime(DateUtils.getNowDate());

            //存储采集数据
            GasDf gasDf=new GasDf();
            String[] list = hexString.toString().split(" ");
            //设备型号
            int protocolId = Integer.parseInt(list[2], 16);
            gasDf.setProtocolId(protocolId);
            //设备唯一编码
            String uuid = String.valueOf(Integer.parseInt(list[3] + list[4] + list[5] + list[6], 16));
            gasDf.setUuid(uuid);
            rectify.setDeviceId(uuid);
            //传感器信息1
            String sensor1 = String.valueOf(Integer.parseInt(list[10] + list[11], 16));
            gasDf.setSensor1(sensor1);
            //传感器信息2
            String sensor2 = String.valueOf(Integer.parseInt(list[12] + list[13], 16));
            gasDf.setSensor2(sensor2);
            //传感器信息3
            String sensor3 = String.valueOf(Integer.parseInt(list[14] + list[15], 16));
            gasDf.setSensor3(sensor3);
            //传感器信息4
            String sensor4 = String.valueOf(Integer.parseInt(list[16] + list[17], 16));
            gasDf.setSensor4(sensor4);
            //气体报警数据
            String qt = BinaryUtil.decimalToBinary(Integer.parseInt(list[34], 16), 8);
            log.info("气体报警8位2进制："+qt);
            if (!(qt.startsWith("00"))){
                log.info("第四路报警");
                int grade = Integer.parseInt(qt.substring(0, 2), 2);
                gasDf.setRoute4(grade);

                rectify.setWarnType("气体浓度报警");
                rectify.setDetection("氧气（O2）");
                rectify.setUnit("%VOL");
                rectify.setConcentration(sensor4.substring(0,2)+"."+sensor4.substring(2));
                rectify.setRoute("第四路报警状态:"+grade+"级报警");
                rectifyService.insertGasWarnRectify(rectify);
            }
            if (!(qt.startsWith("00", 2))){
                log.info("第三路报警");
                int grade = Integer.parseInt(qt.substring(2, 4), 2);
                gasDf.setRoute3(grade);

                rectify.setWarnType("气体浓度报警");
                rectify.setDetection("一氧化碳（CO）");
                rectify.setUnit("PPM");
                rectify.setConcentration(sensor3);
                rectify.setRoute("第三路报警状态:"+grade+"级报警");
                rectifyService.insertGasWarnRectify(rectify);
            }
            if (!(qt.startsWith("00", 4))){
                log.info("第二路报警");
                int grade = Integer.parseInt(qt.substring(4, 6), 2);
                gasDf.setRoute2(grade);

                rectify.setWarnType("气体浓度报警");
                rectify.setDetection("硫化氢（H2S）");
                rectify.setUnit("PPM");
                rectify.setConcentration(sensor2);
                rectify.setRoute("第二路报警状态:"+grade+"级报警");
                rectifyService.insertGasWarnRectify(rectify);
            }

            if (!(qt.startsWith("00", 6))){
                log.info("第一路报警");
                int grade = Integer.parseInt(qt.substring(6, 8), 2);
                gasDf.setRoute1(grade);

                rectify.setWarnType("气体浓度报警");
                rectify.setDetection("甲烷（CH）");
                rectify.setUnit("%LEL");
                rectify.setConcentration(sensor1);
                rectify.setRoute("第一路报警状态:"+grade+"级报警");
                rectifyService.insertGasWarnRectify(rectify);
            }
            //气泵报警等级
            int pump = Integer.parseInt(list[35], 16);
            gasDf.setPump(pump);
            if (pump!=0){
                rectify.setWarnType("气泵报警");
                rectify.setDetection(null);
                rectify.setUnit(null);
                rectify.setConcentration(null);
                rectify.setRoute(pump+"级报警");
                rectifyService.insertGasWarnRectify(rectify);
            }

            SpringUtils.getBean(IGasDfService.class).insertGasDf(gasDf);
        }
        // endregion
    }

    /**
     * 关闭socket
     */
    private void closeSocket() {
        try {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
